package se.recept.kollen.module.bean;

import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.HandlesEvent;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import se.recept.kollen.model.Ingredient;
import se.recept.kollen.model.IngredientCategory;
import se.recept.kollen.model.Product;
import se.recept.kollen.model.ProductCategory;
import se.recept.kollen.module.extension.FragmentResolution;

/**
 *
 * @author jocke
 */
@UrlBinding("/action/ingredient")
public class IngredientActionBean extends DefaultActionBean {

    private static final Logger LOG = Logger.getLogger(LoginActionBean.class.getName());

    @ValidateNestedProperties({
        @Validate(field = "name", on = "addCategory", required = true)
    })
    private IngredientCategory ingredientCategory;

    private IngredientCategory mainCategory;

    @Validate(on = "deleteCategory", required = true)
    private Integer ingredientCategoryId;

    private static final int INGREDIENT_MAX_RESULT = 200;

    @ValidateNestedProperties({
        @Validate(field = "id", on = "removeIngredients", required = true)
    })
    private List<Ingredient> ingredients;

    @Validate(on = "filterByActive", required = true)
    private boolean showActive;

    @Validate(on = "filterBySearch", required = true, trim = true, minlength = 2)
    private String searchText;

    @Inject
    private EntityManager em;

    public IngredientCategory getIngredientCategory() {
        return ingredientCategory;
    }

    public void setIngredientCategory(IngredientCategory productCategory) {
        this.ingredientCategory = productCategory;
    }

    public Integer getIngredientCategoryId() {
        return ingredientCategoryId;
    }

    public void setIngredientCategoryId(Integer ingredientCategoryId) {
        this.ingredientCategoryId = ingredientCategoryId;
    }

    public IngredientCategory getMainCategory() {
        return mainCategory;
    }

    public void setMainCategory(IngredientCategory mainCategory) {
        this.mainCategory = mainCategory;
    }

    public List<Ingredient> getIngredients() {
        return ingredients;
    }

    public void setIngredients(List<Ingredient> products) {
        this.ingredients = products;
    }

    public boolean isShowActive() {
        return showActive;
    }

    public void setShowActive(boolean showActive) {
        this.showActive = showActive;
    }

    public String getSearchText() {
        return searchText;
    }

    public void setSearchText(String searchText) {
        this.searchText = searchText;
    }

    @DefaultHandler
    public Resolution list() {
        populateIngredients();
        populateCategories();
        return new ForwardResolution(Pages.INGREDIENT_OVERVIEW);

    }

    private void populateCategories() {
        final List<IngredientCategory> categories = em.createNamedQuery(IngredientCategory.FIND_BY_CUSTOMER, IngredientCategory.class)
                .setParameter("customer", getCustomer())
                .getResultList();
        getContext().getRequest().setAttribute("categories", categories);
    }

    private void populateIngredients() {
        ingredients = em.createNamedQuery(Ingredient.FIND_ALL, Ingredient.class).setMaxResults(INGREDIENT_MAX_RESULT).getResultList();
        getContext().getRequest().setAttribute("ingredients", ingredients);
    }

    @HandlesEvent("addCategory")
    public Resolution addCategory() {

        IngredientCategory parent = null;

        ingredientCategory.setCustomer(getCustomer());

        if (mainCategory != null && mainCategory.getId() != null) {
            parent = em.find(IngredientCategory.class, mainCategory.getId());
            ingredientCategory.setMainCategory(parent);
        }

        LOG.log(Level.INFO, "Will add product category {0}", ingredientCategory);

        em.persist(ingredientCategory);

        if (parent != null) {
            List<IngredientCategory> parentSubs = (parent.getSubCategories() == null ? new ArrayList<IngredientCategory>() : parent.getSubCategories());
            parentSubs.add(ingredientCategory);
            em.merge(parent);
        }

        populateCategories();

        return new FragmentResolution();
    }

    @HandlesEvent("deleteCategory")
    public Resolution deleteCategory() {

        IngredientCategory category = em.find(IngredientCategory.class, ingredientCategoryId);

        if (category != null) {
            em.remove(category);
        }

        populateCategories();

        LOG.log(Level.INFO, "Will remove products {0}", ingredientCategoryId);

        return new FragmentResolution();
    }

    @HandlesEvent("deleteIngredients")
    public Resolution deleteProducts() {

        LOG.log(Level.INFO, "Will remove {0} ", ingredients);

        for (Ingredient ingredient : ingredients) {
            if (ingredient != null) {
                em.remove(em.find(Product.class, ingredient.getId()));
            }
        }

        populateIngredients();

        return new FragmentResolution();
    }

    @HandlesEvent("filterByActive")
    public Resolution filterByActive() {
        LOG.log(Level.INFO, "Filter  by active {0} ", showActive);

        if (showActive) {

            ingredients = em.createNamedQuery(Ingredient.FIND_BY_ACTIVE, Ingredient.class).setParameter("active", showActive)
                    .setMaxResults(INGREDIENT_MAX_RESULT).getResultList();

            getContext().getRequest().setAttribute("Ingredients", ingredients);

        } else {
            populateIngredients();
        }

        return new FragmentResolution();
    }

    @HandlesEvent("filterBySearch")
    public Resolution filterBySearch() {
        LOG.log(Level.INFO, "Filter  by search {0} ", searchText);
        ingredients = em.createNamedQuery(Ingredient.FIND_BY_LIKE_NAME, Ingredient.class).setParameter("name", "%" + searchText + "%")
                .setMaxResults(INGREDIENT_MAX_RESULT).getResultList();
        getContext().getRequest().setAttribute("Ingredients", ingredients);
        return new FragmentResolution();
    }
}
